package com.wxapp.pay.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wxapp.common.constant.base.IBaseService;
import com.wxapp.common.constant.pojo.vm.ResultVm;
import com.wxapp.common.constant.pojo.vo.UserVo;
import com.wxapp.common.util.check.CheckUtil;
import com.wxapp.common.util.copy.CopyUtil;
import com.wxapp.pay.api.pojo.pojo.entity.PayConfigDO;
import com.wxapp.pay.api.pojo.pojo.entity.PayWayDO;
import com.wxapp.pay.api.pojo.pojo.vm.payConfig.PConfigVm;
import com.wxapp.pay.api.pojo.pojo.vo.payConfig.QConfigVo;
import com.wxapp.pay.service.mapper.PayConfigMapper;
import com.wxapp.pay.service.mapper.PayWayMapper;
import com.wxapp.pay.service.service.PayConfigService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author lgl
 */
@Service
@RequiredArgsConstructor
public class PayConfigServiceImpl extends IBaseService implements PayConfigService {
    private final PayConfigMapper payConfigMapper;
    private final PayWayMapper payWayMapper;
    @Override
    @GlobalTransactional(rollbackFor = {Exception.class, RuntimeException.class})
    public ResultVm<String> addConfigs(String id, List<QConfigVo> qAddVo, UserVo userVo) {
        if (CheckUtil.isNullList(qAddVo)) {
            return error("至少添加一条数据");
        }
        var payWay = payWayMapper.selectById(id);
        if (CheckUtil.isNullObject(payWay)) {
            return error("没有找到信息");
        }
        List<QConfigVo> insertData = new ArrayList<>();
        List<String> payConfigIds = new ArrayList<>();
        AtomicBoolean own = new AtomicBoolean(false);
        qAddVo.forEach(s -> {
            if (CheckUtil.isNotNullString(s.getId())) {
                payConfigIds.add(s.getId());
                if (s.getId().equals(s.getPid())) {
                    own.set(true);
                }
            } else {
                insertData.add(s);
            }
        });
        if (own.get()) {
            return error("父类不能是自己");
        }
        if (!payConfigIds.isEmpty()){
            List<PayConfigDO> payConfigs = payConfigMapper.selectBatchIds(payConfigIds);
            payConfigs.forEach(s -> {
                var first = qAddVo.stream().filter(st -> st.getId().equals(s.getId())).findFirst();
                if (first.isPresent()) {
                    s.setPid(first.get().getPid());
                    s.setUpdateBy(userVo.getId());
                    s.setConfigValue(first.get().getConfigValue());
                    s.setConfigKey(first.get().getConfigKey());
                }
            });
            if (CheckUtil.isNotNullList(payConfigs)) {
                payConfigMapper.batchUpdate(payConfigs);
            }
        }
        if (CheckUtil.isNotNullList(insertData)) {
            List<PayConfigDO> allPayConfigs = CopyUtil.copyListNew(insertData, PayConfigDO::new, (s, r) -> {
                r.setPayWayId(id);
                r.setCreateBy(userVo.getId());
                return null;
            });
            payConfigMapper.insertBatch(allPayConfigs);
        }

        return success("添加成功");
    }

    @Override
    public ResultVm<List<PConfigVm>> getConfigs(String id) {
        var query = new LambdaQueryWrapper<PayConfigDO>();
        query.eq(PayConfigDO::getPayWayId, id).eq(PayConfigDO::getStatus, true);
        var payConfigs = payConfigMapper.selectList(query);
        if (CheckUtil.isNullList(payConfigs)) {
            return success(new ArrayList<>());
        }
        return success(CopyUtil.copyListNew(payConfigs, PConfigVm::new, null));
    }

    @Override
    public ResultVm<Map<String, String>> getConfigsByCode(String code) {
        var queryWay = new LambdaQueryWrapper<PayWayDO>();
        queryWay.eq(PayWayDO::getCode, code).eq(PayWayDO::getStatus, true);
        var payWays = payWayMapper.selectFirst(queryWay);
        if (CheckUtil.isNullObject(payWays)) {
            return success(new HashMap<>());
        }
        var queryConfig = new LambdaQueryWrapper<PayConfigDO>();
        queryConfig.eq(PayConfigDO::getPayWayId, payWays.getId()).eq(PayConfigDO::getStatus, true);
        var payConfigs = payConfigMapper.selectList(queryConfig);
        if (CheckUtil.isNullList(payConfigs)) {
            return success(new HashMap<>());
        }
        return success(payConfigs.stream().collect(Collectors.toMap(PayConfigDO::getConfigKey, PayConfigDO::getConfigValue)));
    }
}
